﻿using System.Windows.Forms;
using Relay.Core.Protocol;
using Relay.Core.Configuration;
using System.IO;
using System;
using System.Collections.Generic;
using System.Reflection;
using Relay.Core.Utility;
using Relay.Core.Plugins;

namespace Relay.Core {
    /// <summary>
    /// Allows the startup project to initialize the application without knowing about a
    /// specific window.
    /// </summary>
    public class ApplicationCore : ApplicationContext {
        private const string ConfigurationFile = "config.xml";
        private readonly string PluginDirectory = Path.Combine(Application.StartupPath, "Plugins");

        #region Fields
        private readonly ApplicationService _appService = null;
        private ConfigurationService _config = null;
        private string _configFileName = String.Empty;
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="AppCore"/> class.
        /// </summary>
        public ApplicationCore() {
            _configFileName = Path.Combine(Application.StartupPath, ConfigurationFile);

            _config = ConfigurationService.Load(_configFileName);
            string interfacePlugin = Path.Combine(PluginDirectory, _config.Get("core", "interface-plugin-path", String.Empty));
            string interfaceClass = _config.Get("core", "interface-plugin-name", String.Empty);

            if (!File.Exists(interfacePlugin)) {
                throw new FileNotFoundException("The specified interface plugin could not be found.", interfacePlugin);
            }

            PluginLoader loader = new PluginLoader(interfacePlugin);

            // attempt to resolve the plugin name
            Type pluginType = loader.GetPluginByName(interfaceClass);
            if (pluginType == null)
                throw new NullReferenceException("The specified interface plugin could not be found.");

            // Attempt to create an instance of the plugin
            IInterfacePlugin plugin = loader.CreateInstance(pluginType) as IInterfacePlugin;
            if (plugin == null)
                throw new NullReferenceException("The specified interface plugin could not be created.");

            _appService = new ApplicationService(plugin);
            _appService.Closing += new System.EventHandler<System.EventArgs>(AppClosing);

            _appService.Config = _config;
        }
        #endregion

        #region Event Handlers
        /// <summary>
        /// Occurs when the main window of the application has closed and terminates the main thread.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void AppClosing(object sender, System.EventArgs e) {
            ExitThread();
        }
        #endregion
    }
}
